<!--
 * @Author: windys
 * @Description: 表格
 * @Date: 2021-12-06 16:31:13
-->
<template>
    <div class="table_box">
        <!-- 表头查询这里不采用vxtable的 -->
        <a-form layout="inline">
            <slot name="filterHade"></slot>
            <a-form-item>
                <a-button type="primary" html-type="submit" @click="handleSaerch">查询</a-button>
            </a-form-item>
        </a-form>

        <!-- 工具 -->

        <vxe-toolbar ref="xToolbar" custom print>
            <template #buttons>
                <vxe-button
                    v-for="btn in buttons"
                    :status="btn.type || 'primary'"
                    :disabled="btn.disabled || false"
                    :key="btn.title"
                    @click="handleClickName(btn.handleName)"
                    :size="btn.size || 'small'"
                    v-show="!btn.show || btn.show()"
                >{{ btn.title }}</vxe-button>
            </template>
        </vxe-toolbar>
        <!-- 表格 -->
        <vxe-table
            class="mytable-scrollbar"
            ref="xTable"
            :align="allAlign"
            :size="size"
            :data="tableData"
            :show-footer="showFooter"
            :footer-method="footerMethod"
            :height="height"
            :stripe="stripe || false"
            :border="border"
            :show-header="showHeader"
            :column-config="columnConfig"
            :row-config="rowConfig"
            :sort-config="tableSort"
            :print-config="printConfig"
            :edit-config="editConfig"
            :edit-rules="validRules"
            resizable
            show-overflow
            keep-source
            :keyboard-config="{ isClip: true }"
            empty-text="没有更多数据了！"
            :span-method="rowspanMethod"
            @header-cell-click="headerCellClickEvent"
            @cell-click="cellClickEvent"
        >
            <vxe-column type="seq" width="50" title="序号" fixed="left"></vxe-column>

            <vxe-column
                v-for="config in tableColumn"
                :key="config.key"
                :type="config.type"
                :field="config.field || null"
                :title="config.title || '标题'"
                :fixed="config.fixed || 'center'"
                :width="config.width"
                :filters="config.filters"
                :show-overflow="config.shwoOverflow || false"
                :sortable="config.sortable || false"
                :formatter="config.formatter || null"
                :edit-render="config.editRender"
            >
                <!-- 编辑类型 -->
                <template #edit="{ row }" v-if="config.solt === 'edit'">
                    <!-- 普通输入 -->
                    <div v-if="config.editType === 'input'">
                        <vxe-input v-model="row[config.field]" type="text"></vxe-input>
                    </div>
                    <!-- 下拉 -->
                    <div v-if="config.editType === 'select'">
                        <vxe-select v-model="row[config.field]" transfer>
                            <vxe-option
                                v-for="item in config.editSelectOptions"
                                :key="item.value"
                                :value="item.value"
                                :label="item.label"
                            ></vxe-option>
                        </vxe-select>
                    </div>
                    <!-- 日期 -->
                    <div v-if="config.editType === 'date'">
                        <vxe-input v-model="row[config.field]" type="date"></vxe-input>
                    </div>
                    <!-- 数字 -->
                    <div v-if="config.editType === 'number'">
                        <vxe-input v-model="row[config.field]" type="number"></vxe-input>
                    </div>
                </template>
                <!-- 展开类型 -->
                <template #content="{ row }">
                    <div style="padding:10px 50px;" v-if="!config.expendType">
                        <m-table
                            ref="mTable"
                            :tableData="row.children"
                            :tableColumn="childrenColumn"
                            :height="200"
                            :showPagination="false"
                        />
                    </div>
                    <div style="padding:10px 50px;" v-else>
                        <component :is="config.compoentName"></component>
                    </div>
                </template>

                <!-- 普通 -->
                <template #default="{ row }">
                    <div v-if="config.type === 'html'" class="defaultCloum">
                        <div v-html="row[config.field]"></div>
                        <i
                            v-if="config.copy"
                            class="iconfont icon-wenzhang"
                            @click="handleCopy(row[config.field])"
                        ></i>
                    </div>
                    <div v-if="!config.type || config.type !== 'html'" class="defaultCloum">
                        <span>{{ row[config.field] }}</span>
                        <i
                            v-if="config.copy"
                            class="iconfont icon-wenzhang"
                            @click="handleCopy(row[config.field])"
                        ></i>
                    </div>
                </template>
            </vxe-column>

            <vxe-column title="操作" v-if="handles.length" show-overflow :width="operaWidth">
                <template #default="{ row, seq }">
                    <!-- <slot name="tableHandle" :row="{ row , seq }"></slot> -->
                    <!-- 通过配置传入 -->
                    <vxe-button
                        v-for="btn in handles"
                        :key="btn.title"
                        :status="btn.status || 'primary'"
                        :size="btn.size || 'small'"
                        v-show="!btn.show || btn.show(row)"
                        @click="handleClickName(btn.handleName, row, seq)"
                    >{{ btn.title }}</vxe-button>
                </template>
            </vxe-column>
        </vxe-table>

        <a-pagination
            v-if="showPagination"
            style="margin-top:10px;text-align: right;"
            v-model:current="current"
            :total="50"
            show-less-items
            show-size-changer
        />
    </div>
</template>


<script lang="ts">
import { defineComponent, PropType, ref, nextTick, unref } from 'vue'
import { VXETable, VxeTablePropTypes, VxeTableEvents, VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx'
import XEUtils from 'xe-utils'
import { useCopyToClipboard } from '../../hook/useCopyToClipboard';
import VXETableFormat from '../../hook/tableFormat'
import { message } from 'ant-design-vue';
import diycomp from './diycomp.vue'
interface options {
    value: string,
    label: string,
}
interface row {
    key?: string | number | any,
    type?: string | any,
    field?: string | any,
    title?: string | any,
    fixed?: string | any,
    width?: string | number,
    filters?: [] | any,
    shwoOverflow?: boolean | any,
    sortable?: boolean | any,
    solt?: string | any,
    editRender?: object | any,
    editType?: string | any,
    editSelectOptions?: Array<options> | undefined,
    formatter?: (<T>() => any) | any,
    copy?: boolean | any,
    expendType?: any,
    compoentName?: any
}
interface btns {
    title?: string | number,
    type?: string | 'primary',
    status?: string | 'primary',
    disabled?: boolean | null | undefined,
    handleName?: string | null | undefined,
    size?: string | null,
    show?: (<T>() => any) | null | undefined | any,
}
const props = {
    tableColumn: {
        type: Array as PropType<row[]>,
        default: () => []
    },
    childrenColumn: {
        type: Array as PropType<row[]>,
        default: () => []
    },
    // 排序index
    showSeq: {
        type: Boolean,
        default: () => !false
    },
    // 表格footer
    showFooter: {
        type: Boolean,
        default: () => false
    },
    // 对齐
    allAlign: {
        type: String,
        default: () => 'center'
    },
    // 高度
    height: {
        type: Number,
        default: () => 600
    },
    // 斑马线
    stripe: {
        type: Boolean,
        default: () => false
    },
    // 边框
    border: {
        type: String,
        default: () => 'full'  //true|full|false|default|outer|inner 
    },
    // 大小
    size: {
        type: String,
        default: () => 'small'
    },
    // 表头显示
    showHeader: {
        type: Boolean,
        default: () => true
    },
    // 编辑模式 手动自动
    editConfig: {
        type: Object,
        default: () => {
            return {
                trigger: 'manual',
                mode: 'row',
                showStatus: true
            }
        }
    },

    columnConfig: {
        type: Object,
        default: () => {
            return {
                resizable: true,
            }
        }
    },
    rowConfig: {
        type: Object,
        default: () => {
            return {
                isHover: true
            }
        }
    },
    printConfig: {
        type: Object,
        default: () => {
            return {}
        }
    },
    // 操作按钮
    operaShow: {
        type: Boolean,
        default: () => true
    },
    // 
    handles: {
        type: Array as PropType<btns[]>,
        default: () => []
    },
    // 操作宽度
    operaWidth: {
        type: Number,
        default: () => {
            return 200
        }
    },
    // 工具栏按钮
    buttons: {
        type: Array as PropType<btns[]>,
        default: () => []
    },
    tableData: {
        type: Array,
        default: () => []
    },
    // 编辑表格校验
    validRules: {
        type: Object,
        default: () => { }
    },
    // 是否显示分页
    showPagination: {
        type: Boolean,
        default: () => true
    }
}
export default defineComponent({
    components: {
        diycomp
    },
    props,
    setup(props, { emit, attrs, slots }) {
        VXETable.use(VXETablePluginExportXLSX)

        const VXETableFormatList = VXETableFormat//table格式化集合

        // 工具栏
        const xTable = ref({} as VxeTableInstance)
        const xToolbar = ref({} as VxeToolbarInstance)
        nextTick(() => {
            // 将表格和工具栏进行关联
            const $table = xTable.value
            const $toolbar = xToolbar.value
            $table.connect($toolbar)
        })
        // 表头
        const headerCellClickEvent: VxeTableEvents.HeaderCellClick = ({ column }) => {
            console.log(`表头单元格点击${column.title}`)
        }
        // 单元
        const cellClickEvent: VxeTableEvents.CellClick = ({ column, row }) => {
            console.log(`单元格点击${column.title}`)
            emit('handleClickName', column.title, row)
        }
        // 合并行  通用行合并函数（将相同多列数据合并为一行）
        const rowspanMethod: VxeTablePropTypes.SpanMethod = ({ row, _rowIndex, column, visibleData }) => {
            const fields = ['name']
            const cellValue = row[column.property]
            if (cellValue && fields.includes(column.property)) {
                const prevRow = visibleData[_rowIndex - 1]
                let nextRow = visibleData[_rowIndex + 1]
                if (prevRow && prevRow[column.property] === cellValue) {
                    return { rowspan: 0, colspan: 0 }
                } else {
                    let countRowspan = 1
                    while (nextRow && nextRow[column.property] === cellValue) {
                        nextRow = visibleData[++countRowspan + _rowIndex]
                    }
                    if (countRowspan > 1) {
                        return { rowspan: countRowspan, colspan: 1 }
                    }
                }
            }
        }
        // 复制
        const { clipboardRef, copiedRef } = useCopyToClipboard();
        const handleCopy = (val: any) => {
            const value = unref(val);
            if (!value) {
                console.log('请输入要拷贝的内容！');
                return;
            }
            clipboardRef.value = value;
            if (unref(copiedRef)) {
                message.success('复制成功！')
            }
        }
        // 导出
        const exportDataEvent = () => {
            const $table = xTable.value
            $table.exportData({
                filename: '导出',
                sheetName: 'Sheet1',
                type: 'xlsx'
            })
        }

        const sumNum = (list: any[], field: string) => {
            let count = 0
            list.forEach(item => {
                count += Number(item[field])
            })
            return count
        }
        const footerMethod: VxeTablePropTypes.FooterMethod = ({ columns, data }) => {
            return [
                columns.map((column, columnIndex) => {
                    if (columnIndex === 0) {
                        return '平均'
                    }
                    if (['age'].includes(column.property)) {
                        return sumNum(data, column.property)
                    }
                    return '-'
                })
            ]
        }
        // 排序
        const getPinYin = (str: string) => {
            return str.split('').map(char => {
                switch (char.charAt(0)) {
                    case '老': return 'lao'
                    case '小': return 'xiao'
                    case '前': return 'qian'
                    case '好': return 'hao'
                    case '王': return 'wang'
                    case '红': return 'hong'
                    case '明': return 'ming'
                    case '吧': return 'ba'
                    case '踢': return 'ti'
                }
                return char.charAt(0)
            }).join('')
        }
        const tableSort = ref({
            sortMethod({ data, sortList }) {
                const sortItem = sortList[0]
                // 取出第一个排序的列
                const { property, order } = sortItem
                let list: any[] = []
                if (order === 'asc' || order === 'desc') {
                    if (property === 'name') {
                        // 例如：实现中英文混排，按照字母排序
                        list = data.sort((a, b) => {
                            return getPinYin(a.name).localeCompare(getPinYin(b.name))
                        })
                    } else {
                        list = data.sort()
                    }
                }
                if (order === 'desc') {
                    list.reverse()
                }
                return list
            }
        } as VxeTablePropTypes.SortConfig)

        // 表格所有往外事件
        const handleClickName = (name: any, row?: any, seq?: any) => {
            emit('handleClickName', name, row, seq)
        }

        // 查询
        const handleSaerch = () => {
            emit('handleSaerch')
        }
        return {
            current: ref(2),
            handleCopy,
            exportDataEvent,
            footerMethod,
            rowspanMethod,
            tableSort,
            xTable,
            xToolbar,
            VXETableFormatList,
            headerCellClickEvent,
            cellClickEvent,
            handleClickName,
            handleSaerch
        }
    },
})
</script>


<style lang="scss" scoped>
/*滚动条整体部分*/
.mytable-scrollbar ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
    padding-bottom: 50px;
}
/*滚动条的轨道*/
.mytable-scrollbar ::-webkit-scrollbar-track {
    background-color: #ffffff;
}
/*滚动条里面的小方块，能向上向下移动*/
.mytable-scrollbar ::-webkit-scrollbar-thumb {
    background-color: #bfbfbf;
    border-radius: 5px;
    border: 1px solid #f1f1f1;
    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
.mytable-scrollbar ::-webkit-scrollbar-thumb:hover {
    background-color: #a8a8a8;
}
.mytable-scrollbar ::-webkit-scrollbar-thumb:active {
    background-color: #787878;
}
/*边角，即两个滚动条的交汇处*/
.mytable-scrollbar ::-webkit-scrollbar-corner {
    background-color: #ffffff;
}

.defaultCloum {
    display: flex;
    flex-direction: row;
    justify-content: center;
}
.iconfont {
    cursor: pointer !important;
    color: #00a2ff !important;
}
</style>